package com.xyq.fs.scan;

import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import com.xyq.fs.base.MyDirectoryS;
import com.xyq.fs.constants.IndexStringConstants;
import com.xyq.fs.constants.NoIndexNamesConstant;
import com.xyq.fs.constants.ParseConstant;
import com.xyq.fs.contants.filesuffixes2.ExcelEnums;
import com.xyq.fs.contants.filesuffixes2.OtherEnums;
import com.xyq.fs.contants.filesuffixes2.PdfEnums;
import com.xyq.fs.contants.filesuffixes2.PptEnums;
import com.xyq.fs.contants.filesuffixes2.TxtEnums;
import com.xyq.fs.contants.filesuffixes2.WordEnums;
import com.xyq.fs.index.IndexFileInf;

import com.xyq.fs.task.MyTask;
import com.xyq.fs.views.WindwosA;

/**
 * 扫描文件接口 1.可开始,可暂停
 * 
 * @author xyqq
 *
 */
public class ScanFileImpl implements FileVisitor<Path> {

	// private static long maxSize = 1024 * 1024 * 2048;

	// C盘只扫描用户文件夹

	ExecutorService pool;
	private String fileType;
	private boolean needUpdateUi = false;
	private boolean needUpdateDoc = false;
	private Future<?> fu = null;
	private int bai = 100;

	/***
	 * 
	 * @param pool
	 * @param fileType
	 *            扫描或搜索什么类型的文件
	 */
	public ScanFileImpl(ExecutorService pool, String fileType) {

		this.pool = pool;
		this.fileType = fileType;
	}

	@Override
	public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {

		if (WindwosA.getSLEEP_NOW().get() == 4)
			return FileVisitResult.TERMINATE;
		while (WindwosA.getSLEEP_NOW().get() == 2) {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		String dirs = dir.toString();
		String dirRs = dir.getRoot().toString();
		// C盘只扫描user文件夹
		if (NoIndexNamesConstant.C.equals(dirRs)) {
			if (!dirs.startsWith(NoIndexNamesConstant.CUSER) && !NoIndexNamesConstant.C.equals(dirs)) {
				return FileVisitResult.SKIP_SUBTREE;
			}
		}

		dirs = null;
		dirRs = null;
		dir = null;
		attrs = null;
		return FileVisitResult.CONTINUE;
	}

	int tempnum = 0;

	MyTask my = new MyTask(null, null, -1, false, false);

	@Override
	public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {

		// 根据最后访问时间确实文件是否需要被索引
		if (WindwosA.getCb1().isSelected() || !attrs.lastAccessTime().equals(attrs.lastModifiedTime())) {

			while (WindwosA.getSLEEP_NOW().get() == 2) {
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}

			if (WindwosA.getSLEEP_NOW().get() == 4)
				return FileVisitResult.TERMINATE;

			String fname = file.getFileName().toString().toUpperCase();
			int n = fname.lastIndexOf(".");
			IndexFileInf iff = null;
			if (n != -1 && fname.length() > 3 && !fname.startsWith(NoIndexNamesConstant.PIE)
					&& (fname.indexOf(NoIndexNamesConstant.LUCENE) == -1
							&& fname.indexOf(NoIndexNamesConstant.GANG) == -1)) {

				switch (fileType) {

				// 全部类型包含文本类型和非文本类型
				case IndexStringConstants.QBLX:
					if (TxtEnums.suffixContains(fname))
						iff = ParseConstant.itf;
					else if (fname.endsWith(PdfEnums.PDF)) {
						iff = ParseConstant.ipf;
					} else if (PptEnums.suffixContains(fname)) {
						iff = ParseConstant.ippf;
					} else if (WordEnums.suffixContains(fname)) {
						iff = ParseConstant.iwf;
					} else if (ExcelEnums.suffixContains(fname)) {
						iff = ParseConstant.ief;
					} else if (OtherEnums.suffixContains(fname) && !WindwosA.getCb2().isSelected())
						iff = ParseConstant.ifn;
					break;
				// 需要扫描文本类型
				case IndexStringConstants.WBLX:
					if (TxtEnums.suffixContains(fname)) {
						iff = ParseConstant.itf;
					}
					break;
				// 非全部类型且非文本类型
				default:
					if (fname.endsWith(fileType)) {
						if (fname.endsWith(PdfEnums.PDF)) {
							iff = ParseConstant.ipf;
						} else if (PptEnums.suffixContains(fname)) {
							iff = ParseConstant.ippf;
						} else if (WordEnums.suffixContains(fname)) {
							iff = ParseConstant.iwf;
						} else if (ExcelEnums.suffixContains(fname)) {
							iff = ParseConstant.ief;
						} else if (TxtEnums.suffixContains(fname))
							iff = ParseConstant.itf;
					} else if (OtherEnums.suffixContains(fname) && !WindwosA.getCb2().isSelected())
						iff = ParseConstant.ifn;
					break;
				}
				needUpdateUi = false;
				needUpdateDoc = false;
				if (iff != null) {
					// //每100提交一次
					if (tempnum > 0) {
						if (tempnum / bai > 1) {
							bai += 150;
							needUpdateDoc = true;
							MyDirectoryS.updateReaderAndSearcher();
							System.gc();
							System.out.println("提交了" + tempnum);
						}
					}
					//
					if (tempnum > 0 && tempnum % 20 == 0) {
						needUpdateUi = true;
					}

					my.setIff(iff);
					my.setPath(file);
					my.setTempnum(tempnum);
					my.setNeedUpdateUi(needUpdateUi);
					my.setNeedUpdateDoc(needUpdateDoc);
					fu = pool.submit(my);

					try {
						if (WindwosA.getCb2().isSelected())
							fu.get(8, TimeUnit.SECONDS);
						else
							fu.get(30, TimeUnit.SECONDS);
					} catch (Exception e1) {
						System.out.println(file + "在指定时间内没有索引完,任务放弃");
						System.gc();
					}
					tempnum++;
					try {
						Files.setAttribute(file, IndexStringConstants.LASTACCTIME, attrs.lastModifiedTime());
					} catch (IOException e) {
						System.out.println(file + "同步失败");
					}
					iff = null;
				}
				fname = null;
			}
		}
		file = null;

		return FileVisitResult.CONTINUE;

	}

	@Override
	public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {

		file = null;
		exc = null;
		return FileVisitResult.CONTINUE;
	}

	@Override
	public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {

		dir = null;
		exc = null;
		return FileVisitResult.CONTINUE;
	}

}
